package cn.com.yusys.yusp.admin.service;

import cn.com.yusys.yusp.admin.domain.*;
import cn.com.yusys.yusp.admin.repository.mapper.*;
import cn.com.yusys.yusp.commons.exception.MessageConstants;
import cn.com.yusys.yusp.commons.exception.YuspException;
import cn.com.yusys.yusp.commons.mapper.CommonMapper;
import cn.com.yusys.yusp.commons.mapper.QueryModel;
import cn.com.yusys.yusp.commons.service.CommonService;
import cn.com.yusys.yusp.commons.util.BCRSAUtil;
import cn.com.yusys.yusp.commons.util.DateUtil;
import com.github.pagehelper.PageHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @项目名称: yusp-admin
 * @类名称: AdminSmUserService
 * @类描述:
 * @功能描述:
 * @创建人: hujun3@yusys.com.cn
 * @创建时间: 2017-12-25 10:53
 * @修改备注:
 * @修改记录: 修改时间 修改人员 修改原因
 * -------------------------------------------------------------
 * @Copyright (c) 2018宇信科技-版权所有
 */
@Service
public class AdminSmUserService extends CommonService {
    private Logger logger = LoggerFactory.getLogger(AdminSmUserService.class);
    @Autowired
    private AdminSmUserMapper mapper;
    @Autowired
    private AdminSmUserRoleRelMapper roelRelMapper;
    @Autowired
    private AdminSmUserDutyRelMapper dutyRelMapper;
    @Autowired
    private AdminSmUserMgrOrgMapper orgRelMapper;
    @Autowired
    private AdminSmPasswordLogMapper pwdMapper;
    @Autowired
    private MessageProviderService messageProviderService;

    private static final String SUCCESS = "success";

    @Override
    protected CommonMapper<?> getMapper() {
        return this.mapper;
    }

    /**
     * @方法名称: findAllByParam
     * @方法描述: 分页查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> findAllByParam(QueryModel param) {
        // 设置分页查询参数(设置到线程变量中了)
        PageHelper.startPage(param.getPage(), param.getSize());
        List<Map<String, Object>> result = this.mapper.queryUserByPage(param);
        PageHelper.clearPage();
        return result;
    }

    /**
     * @方法名称: getListByRolests
     * @方法描述: 查询角色数据，只可关联用户所在机构及上级机构的生效角色
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getListByRolests(String orgId) {
        List<Map<String, Object>> result = new ArrayList<>();
        String orgIdSeq = this.mapper.getOrgIds(orgId);
        if (orgIdSeq != null && !orgIdSeq.equals("")) {
            String[] orgIds = orgIdSeq.split(",");
            result = this.mapper.getListByRolests(orgIds);
        }
        return result;
    }

    /**
     * @方法名称: findUserRole
     * @方法描述: 用户角色数据查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> findUserRole(QueryModel param) {
        // 设置分页查询参数(设置到线程变量中了)
        PageHelper.startPage(param.getPage(), param.getSize());
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("userId", param.getCondition().get("paramId").toString());
        List<Map<String, Object>> result = this.mapper.getUserRole(paramMap);
        PageHelper.clearPage();
        return result;
    }

    /**
     * @方法名称: findUserOrg
     * @方法描述: 用户授权机构数据查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> findUserOrg(QueryModel param) {
        // 设置分页查询参数(设置到线程变量中了)
        PageHelper.startPage(param.getPage(), param.getSize());
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("userId", param.getCondition().get("paramId").toString());
        List<Map<String, Object>> result = this.mapper.getUserOrg(paramMap);
        PageHelper.clearPage();
        return result;
    }

    /**
     * @方法名称: getListByRolests
     * @方法描述: 查询岗位数据，只可关联用户所在机构及上级机构的生效岗位
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getListByDuty(String orgId) {
        List<Map<String, Object>> result = new ArrayList<>();
        String orgIdSeq = this.mapper.getOrgIds(orgId);
        if (orgIdSeq != null && !orgIdSeq.equals("")) {
            String[] orgIds = orgIdSeq.split(",");
            result = this.mapper.getListByDuty(orgIds);
        }
        return result;
    }

    /**
     * @方法名称: findUserDuty
     * @方法描述: 用户岗位数据查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> findUserDuty(QueryModel param) {
        // 设置分页查询参数(设置到线程变量中了)
        PageHelper.startPage(param.getPage(), param.getSize());
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("userId", param.getCondition().get("paramId").toString());
        List<Map<String, Object>> result = this.mapper.getUserDuty(paramMap);
        PageHelper.clearPage();
        return result;
    }

    /**
     * @方法名称: updateSts
     * @方法描述: 修改用户状态
     * @参数与返回说明: sts -用户状态| userId 用户ID
     * @算法描述:
     */
    public int updateSts(String sts, String userId, String lastChgUsr) {
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("id", userId);
        paramMap.put("sts", sts);
        paramMap.put("user", lastChgUsr);
        paramMap.put("date", DateUtil.formatDateTimeByDef());
        int result = this.mapper.updateUserSts(paramMap);
        return result;
    }

    /**
     * @方法名称: removeUserRaleInfo
     * @方法描述: 删除用户的关联数据
     * @参数与返回说明: type -删除类似 userId 用户ID
     * @算法描述:
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int removeUserRaleInfo(String userId, String type) {
        int result = 0;
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("userId", userId);
        if ("role".equals(type)) {
            result = this.mapper.removeUserRole(paramMap);
        } else if ("duty".equals(type)) {
            result = this.mapper.removeUserDuty(paramMap);
        } else if ("org".equals(type)) {
            result = this.mapper.removeUserOrg(paramMap);
        }
        return result;
    }

    /**
     *
     * @return
     */
    @Transactional
    public int updateUserPassword(Map<String, Object> map) {
        Map<String, Object> result = mapper.selectUserByUserId(map);
        String newPassword = null;
        String oldPassword = null;
        int updateStatus = 0 ;
        Map<String,Object> passwordMap = new HashMap<>();
        try {
            newPassword = BCRSAUtil.decryptByPrivate((String) map.get("newPassword"));
            oldPassword = BCRSAUtil.decryptByPrivate((String) map.get("oldPassword"));
            passwordMap.put("newPassword",new BCryptPasswordEncoder().encode(newPassword));
            passwordMap.put("userId",map.get("userId"));
            boolean check = new BCryptPasswordEncoder().matches(oldPassword, (String) result.get("userPassword"));
            if (check){
                updateStatus =  mapper.updateUserPassword(passwordMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return updateStatus;
    }

    /**
     * @方法名称: insertInfo
     * @方法描述: 新增用户数据
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public Map<String, Object> insertInfo(AdminSmUser pool) {
        Map<String, Object> result = new HashMap<String, Object>();

        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("loginCode", pool.getLoginCode());
        List<Map<String, Object>> res = mapper.findQueryUserByParam(paramMap);// 查询用户（登录代码）是否已存在
        if (res.size() == 0) {
            pool.setLastChgDt(DateUtil.formatDateTimeByDef());// 最近跟新时间
            if (pool.getUserSts() == null || "".equals(pool.getUserSts())) {
                pool.setUserSts("A");// 新增的数据都是默认生效的
            }
            if (pool.getDeadline() != null && !"".equals(pool.getDeadline())) {
                pool.setDeadline(pool.getDeadline().substring(0, 10));
            }
            if (pool.getUserBirthday() != null && !"".equals(pool.getUserBirthday())) {
                pool.setUserBirthday(pool.getUserBirthday().substring(0, 10));
            }
            if (pool.getEntrantsDate() != null && !"".equals(pool.getEntrantsDate())) {
                pool.setEntrantsDate(pool.getEntrantsDate().substring(0, 10));
            }
            pool.setLastEditPassTime("");
            pool.setUserId(pool.getLoginCode());
            pool.setLastLoginTime("");
            logger.info("New user data: [new user: {}] ", pool.getUserName());

            try {
                String cipherText = BCRSAUtil.decryptByPrivate(pool.getUserPassword());
                pool.setUserPassword(new BCryptPasswordEncoder().encode(cipherText));
            } catch (Exception e) {
                logger.error("BC decryption failed", e);
                e.printStackTrace();
            }
            this.insert(getMapper(), pool);

            String lastChgUsr = pool.getLastChgUsr();
            String userId = pool.getUserId();
            updatePwdLog(pool.getUserPassword(), userId, lastChgUsr);// 保存密码历史记录

            result.put("message", "用户代码为：" + pool.getUserCode() + ",用户名称为:" + pool.getUserName() + "的数据保存成功。");
        } else {// 如果已存在就不能新增
            logger.error("Data with login code " + pool.getLoginCode() + " is already exists.");
            throw new YuspException(messageProviderService.getMessage(String.valueOf(MessageConstants.RET_CODE_20100007)));
        }
        return result;
    }

    /**
     * @方法名称: update
     * @方法描述: 修改用户数据
     * @参数与返回说明:
     * @算法描述:
     */
    @Override
    public int update(Object record) {
        AdminSmUser pool = (AdminSmUser) record;
        AdminSmUser osData = this.mapper.selectByPrimaryKey(pool.getUserId());
        pool.setLastChgDt(DateUtil.formatDateTimeByDef());// 最近跟新时间
        if (pool.getUserSts() == null || "".equals(pool.getUserSts())) {
            pool.setUserSts("A");// 新增的数据都是生效的
        }
        if (pool.getDeadline() != null && !"".equals(pool.getDeadline())) {
            pool.setDeadline(pool.getDeadline().substring(0, 10));
        }
        if (pool.getUserBirthday() != null && !"".equals(pool.getUserBirthday())) {
            pool.setUserBirthday(pool.getUserBirthday().substring(0, 10));
        }
        if (pool.getEntrantsDate() != null && !"".equals(pool.getEntrantsDate())) {
            pool.setEntrantsDate(pool.getEntrantsDate().substring(0, 10));
        }
        if (osData.getLastEditPassTime() == null || "".equals(osData.getLastEditPassTime())) {
            pool.setLastEditPassTime("");
        } else {
            pool.setLastEditPassTime(osData.getLastEditPassTime());
        }
        if (osData.getLastLoginTime() == null || "".equals(osData.getLastLoginTime())) {
            pool.setLastLoginTime("");
        } else {
            pool.setLastLoginTime(osData.getLastLoginTime());
        }
        logger.info("用User modified data: [modify user: {}] ", pool.getUserName());
        return this.updateSelective(getMapper(), pool);
    }

    /**
     * @方法名称: addUserRole
     * @方法描述: 新增用户和角色关联数据
     * @参数与返回说明:
     * @算法描述:
     */
    public int addUserRole(Object record) {
        AdminSmUserRoleRel pool = (AdminSmUserRoleRel) record;
        pool.setLastChgDt(DateUtil.formatDateTimeByDef());// 最近跟新时间
        if (pool.getRelSts() == null || "".equals(pool.getRelSts())) {
            pool.setRelSts("A");// 新增的数据都是生效的
        }
        return roelRelMapper.insert(pool);
    }

    /**
     * @方法名称: addUserDuty
     * @方法描述: 新增用户岗位关联数据
     * @参数与返回说明:
     * @算法描述:
     */
    public int addUserDuty(Object record) {
        AdminSmUserDutyRel pool = (AdminSmUserDutyRel) record;
        pool.setLastChgDt(DateUtil.formatDateTimeByDef());// 最近跟新时间
        if (pool.getRelSts() == null || "".equals(pool.getRelSts())) {
            pool.setRelSts("A");// 新增的数据都是生效的
        }
        return dutyRelMapper.insert(pool);
    }

    /**
     * @方法名称: addUserOrg
     * @方法描述: 新增用户机构关联数据
     * @参数与返回说明:
     * @算法描述:
     */
    public int addUserOrg(Object record) {
        AdminSmUserMgrOrg pool = (AdminSmUserMgrOrg) record;
        pool.setLastChgDt(DateUtil.formatDateTimeByDef());// 最近跟新时间
        if (pool.getRelSts() == null || "".equals(pool.getRelSts())) {
            pool.setRelSts("A");// 新增的数据都是生效的
        }
        return orgRelMapper.insert(pool);
    }

    /**
     * @方法名称: resetPassword
     * @方法描述: 重置用户密码, 无需旧密码
     * @参数与返回说明:
     * @算法描述:重置密码的同时保存密码历史记录
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public String resetUserPassword(Map map) {
        String password = String.valueOf(map.get("password"));
        String userId = String.valueOf(map.get("userId"));
        String updateUser = String.valueOf(map.get("updateUser"));
        if (password != null && !"".equals(password) && userId != null && !"".equals(userId) && updateUser != null && !"".equals(updateUser)) {
            try {
                String cipherText = BCRSAUtil.decryptByPrivate(password);
                password = new BCryptPasswordEncoder().encode(cipherText);
            } catch (Exception e) {
                logger.error("BC decryption failed", e);
                e.printStackTrace();
            }
            map.put("password", password);
            if (updateUser.equals(userId)) {
                map.put("loginTime", DateUtil.formatDateTimeByDef());
            }
            map.put("lastEditPassTime", DateUtil.formatDateTimeByDef());
            map.put("lastChgUsr", updateUser);
            map.put("lastChgDt", DateUtil.formatDateTimeByDef());
            mapper.resetUserPassword(map);// 修改用户密码

            String res = updatePwdLog(password, userId, userId);// 新增密码历史记录
            logger.info(res);
            return res;
        }else{
            throw new YuspException(messageProviderService.getMessage(String.valueOf(MessageConstants.RET_CODE_20100011)));
        }
    }

    /**
     * 更新密码日志
     *
     * @param encryptPwd
     * @param userId
     * @param lastChgUsr
     * @return
     */
    public String updatePwdLog(String encryptPwd, String userId, String lastChgUsr) {
        AdminSmPasswordLog pwd = new AdminSmPasswordLog();
        pwd.setLastChgDt(DateUtil.formatDateTimeByDef());
        pwd.setLastChgUsr(lastChgUsr);
        pwd.setPwdUped(encryptPwd);
        pwd.setUpdateUser(lastChgUsr);
        pwd.setPwdUpTime(DateUtil.formatDateTimeByDef());
        pwd.setUserId(userId);
        int res = pwdMapper.insert(pwd);// 新增密码历史记录
        logger.info("" + res);
        if (res > 0) {
            return SUCCESS;
        } else {
            throw new YuspException(messageProviderService.getMessage(String.valueOf(MessageConstants.RET_CODE_20100011)));
        }
    }

    /**
     * 根据登录代码获取用户Id
     *
     * @param loginCode
     * @return
     */
    public String getUserIdByLoginCode(String loginCode) {
        String res = this.mapper.getUserIdByLoginCode(loginCode);
        return res;
    }

}
